package com.sensetime.bi.senselink.server.handler;

import com.sensetime.bi.senselink.server.entity.RtspRequestMsg;
import com.sensetime.bi.senselink.server.rtsp.server.processor.IRtspRequest;
import com.sensetime.bi.senselink.server.rtsp.session.RtspSessionIdFactory;
import com.sensetime.bi.senselink.server.rtsp.session.SessionManager;
import com.sensetime.bi.senselink.server.rtsp.session.SimpleRandomIdFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.rtsp.RtspMethods;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class RtspRequestHandler extends SimpleChannelInboundHandler<RtspRequestMsg> {
    public static final RtspSessionIdFactory keyFactory = new SimpleRandomIdFactory();

    //保留所有与服务器建立连接的channel对象
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private IRtspRequest requestProcessor;

    public RtspRequestHandler(IRtspRequest requestProcessor) {
        this.requestProcessor = requestProcessor;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RtspRequestMsg msg) throws Exception {
        //log.info("RTSP消息，Method: {}, body:{}", msg.getMethod(), msg.getContent());
        Channel channel = ctx.channel();
        if (msg.getMethod().equalsIgnoreCase(RtspMethods.OPTIONS.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.OPTIONS);
            requestProcessor.onOptionRequest(msg, channel);
        } else if (msg.getMethod().equalsIgnoreCase(RtspMethods.DESCRIBE.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.DESCRIBE);
            requestProcessor.onDescribeRequest(msg, channel);
        } else if (msg.getMethod().equalsIgnoreCase(RtspMethods.SETUP.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.SETUP);
            requestProcessor.onSetupRequest(msg, channel);
        } else if (msg.getMethod().equalsIgnoreCase(RtspMethods.GET_PARAMETER.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.GET_PARAMETER);
            requestProcessor.onGetParameterRequest(msg, channel);
        } else if (msg.getMethod().equalsIgnoreCase(RtspMethods.PLAY.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.PLAY);
            requestProcessor.onPlayRequest(msg, channel);
        } else if (msg.getMethod().equalsIgnoreCase(RtspMethods.PAUSE.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.PAUSE);
            requestProcessor.onPauseRequest(msg, channel);
        } else if (msg.getMethod().equalsIgnoreCase(RtspMethods.TEARDOWN.name())) {
//            channel.attr(CONNECTION_STATUS).set(RtspMethods.TEARDOWN);
            requestProcessor.onTeardownRequest(msg, channel);
        } else {
            log.error("Method: {} not support!", msg.getMethod());
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.add(channel);
        log.info("RTSP client【服务器】 -" +channel.remoteAddress() +" 加入, 当前所有RTSP客户端连接数：" + channelGroup.size());

        // 创建会话信息
        SessionManager.createPlayerSession(channel);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        log.info("RTSP client【服务器】 -" +channel.remoteAddress() +" 离开, 当前所有RTSP客户端连接数：" + channelGroup.size());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("new RTSP client:[" + ctx.channel().remoteAddress() + "] connected!, total client count：" + channelGroup.size());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("new RTSP client:[" + ctx.channel().remoteAddress() + "] disconnected!, total client count：" + channelGroup.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("RTSP client:[" + ctx.channel().remoteAddress() + "] exception happened:" + cause.getMessage(), cause);
    }
}
